﻿using pe.edu.pucp.lp2.model.bean;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.IO;
using SalesModel;
using SalesController;

namespace pe.edu.pucp.lp2.controller
{

    public class DBConnection
    {
        public static int dbType = DAOFactory.SQLSERVER;
    }
    //BASE DE DATOS DE STORE
    [Serializable]
    public class StoresDB
    {
        DAOFactory daoFactory = null;
        DAOStore daoStore = null;

        public StoresDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoStore = daoFactory.getDAOStore(); //Polimorfismo
        }

        public List<Store> Values
        {
            get { return daoStore.queryAll(); }
        }
        public void Add(Store s)
        {
            //productList.Add(p);
            daoStore.add(s);
        }
        public int Size
        {
            get { return daoStore.count(); }
        }
        public void Delete(int i)
        {
            //productList.RemoveAt(i);
            daoStore.delete(i);
        }
        public void Update(Store p)
        {
            daoStore.update(p);
        }
        public Store QueryById(int storeId)
        {
            return daoStore.queryById(storeId);
        }
    }
    //BASE DE DATOS DE PRODUCTOS
   
    [Serializable]
    public class ProductsDB
    {
        DAOFactory daoFactory = null;
        DAOProduct daoProduct = null;

        public ProductsDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoProduct = daoFactory.getDAOProduct(); //Polimorfismo
        }

        public List<Product> Values
        {
            get { return daoProduct.queryAll(); }
        }
        public void Add(Product p)
        {
            //productList.Add(p);
            daoProduct.add(p);
        }
        public int Size
        {
            get { return daoProduct.count(); }
        }
        public void Delete(int i)
        {
            //productList.RemoveAt(i);
            daoProduct.delete(i);
        }
        public void Update(Product p)
        {
            daoProduct.update(p);
        }
        public Product QueryById(int productId)
        {
            return daoProduct.queryById(productId);
        }
    }

    //BASE DE DATOS DE CLIENTES

    [Serializable]
    public class CustomersDB
    {
        DAOFactory daoFactory = null;
        DAOCustomer daoCustomer = null;
        public CustomersDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoCustomer = daoFactory.getDAOCustomer(); //Polimorfismo
        }
        public List<Customer> Values
        {
            get { return daoCustomer.queryAll(); }
        }

        public void Add(Customer c)
        {
            daoCustomer.add(c);
        }

        public int Size
        {
            get { return daoCustomer.count(); }
        }

        public void Delete(String id)
        {
            daoCustomer.delete(id);
        }
        public void Update(Customer c)
        {
            daoCustomer.update(c);
        }
        public Customer QueryById(int customerId)
        {
            return daoCustomer.queryById(customerId);
        }
    }

    [Serializable]
    public class PriceByDateDB
    {
        DAOFactory daoFactory = null;
        DAOPriceByDate daoPriceByDate = null;
        public PriceByDateDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoPriceByDate = daoFactory.getDAOPriceByDate();
        }
        public List<PriceByDate> Values
        {
            get
            {
                return daoPriceByDate.queryAll();
            }
        }
        public void Add(PriceByDate pd)
        {
            daoPriceByDate.add(pd);
        }
        public int Size()
        {
            return daoPriceByDate.count();
        }
        public void Delete(int i)
        {
            daoPriceByDate.delete(i);
        }
        public void Update(PriceByDate pd)
        {
            daoPriceByDate.update(pd);
        }
        public PriceByDate QueryById(int id)
        {
            return daoPriceByDate.queryByIdProduct(id);
        }
    }
    public class SalesDB
    {
        DAOFactory daoFactory = null;
        DAOSale daoSales = null;

        public SalesDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoSales = daoFactory.getDAOSales(); //Polimorfismo
        }
        public List<Sale> Values
        {
            get { return daoSales.queryAll(); }
        }
        public void Add(Sale s)
        {
            //productList.Add(p);
            daoSales.add(s);
        }
        public int Size
        {
            get { return daoSales.count(); }
        }
        public void Delete(int i)
        {
            //productList.RemoveAt(i);
            daoSales.delete(i);
        }
        public void Update(Sale s)
        {
            daoSales.update(s);
        }
        public Sale QueryById(int salesId)
        {
            return daoSales.queryById(salesId);
        }
    }

    public class SalesDetailDB
    {
        DAOFactory daoFactory = null;
        DAOSaleDetail daoSaleDetail = null;

         public SalesDetailDB()
        {
            daoFactory = DAOFactory.getDAOFactory(DBConnection.dbType);
            daoSaleDetail = daoFactory.getDAOSaleDetail(); //Polimorfismo
        }
        public void Add(SalesDetail sd, int saleId)
        {
            daoSaleDetail.add(sd,saleId);
        }
        public void Delete(SalesDetail sd)
        {
            daoSaleDetail.delete(sd);
        }
        public void Update(SalesDetail sd,int saleId)
        {
            daoSaleDetail.update(sd,saleId);
        }
        public List<SalesDetail> QueryById(int saleId)
        {
            return daoSaleDetail.queryById(saleId);
        }
    }
    public class SalesManager
    {
        private static ProductsDB products = new ProductsDB();
        private static CustomersDB customers = new CustomersDB();
        private static SalesDetailDB saledetails = new SalesDetailDB();
        private static StoresDB stores = new StoresDB();
        private static List<Cashier> cashierList = new List<Cashier>();
        private static List<StoreManager> storeManagerList = new List<StoreManager>();
        private static CashierDB cashiers = new CashierDB();
        private static StoreManagerDB storeManagers = new StoreManagerDB();
        private static SalesDB sales = new SalesDB();

        //MANTENIMIENTO DE STOREMANAGER
        //Agregar un StoreManager a la lista de StoreManager
        public static void addStoreManager(StoreManager s)
        {
            storeManagerList.Add(s);
        }

        //Devuelve true si el StoreManager, con dicho id, está en la lista de StoreManager,
        //"False" si no esta en la lista
        public static Boolean isInManagerList(int id)
        {
            for (int i = 0; i < storeManagerList.Count(); i++)
            {
                if (storeManagerList.ElementAt(i).getId() == id)
                    return true;
            }

            return false;
        }

        //Obtiene un StoreManager por id de la lista de StoreManager
        public static StoreManager getManagerById(int id)
        {
            StoreManager c = new StoreManager();
            for (int i = 0; i < storeManagerList.Count(); i++)
            {
                if (storeManagerList.ElementAt(i) is Employee)
                {
                    if (((Employee)storeManagerList.ElementAt(i)).getId() == id)
                    {
                        c = storeManagerList.ElementAt(i);
                        return c;
                    }
                }
            }
            return null;
        }
        //Obtiene el token de un StoreManager por su id
        public static int getTokenById(int id)
        {
            for (int i = 0; i < storeManagerList.Count(); i++)
            {
                if (storeManagerList.ElementAt(i).getId() == id)
                    return storeManagerList.ElementAt(i).getToken();
            }
            return -1;

        }


        //SERIALIZACION

        //Creación de XML de cada base de datos

        public static void PersistProductsDB(String filename)
        {
            XmlSerializer writer = new XmlSerializer(typeof(ProductsDB));
            TextWriter file = new StreamWriter(filename);
            writer.Serialize(file, products);
            file.Close();
        }

        public static void PersistCustomersDB(String filename)
        {
            XmlSerializer writer = new XmlSerializer(typeof(CustomersDB));
            TextWriter file = new StreamWriter(filename);
            writer.Serialize(file, customers);
            file.Close();
        }

        public static void Venta2(String filename, Sale s)
        {
            XmlSerializer writer = new XmlSerializer(typeof(Sale));
            TextWriter file = new StreamWriter(filename);
            writer.Serialize(file, s);
            file.Close();
        }

        //Carga de bases de datos desde XML

        public static void ReloadProductsDB(String filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ProductsDB));
            FileStream fs = new FileStream(filename, FileMode.Open);
            products = (ProductsDB)serializer.Deserialize(fs);
            fs.Close();
        }

        public static void ReloadCustomersDB(String filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(CustomersDB));
            FileStream fs = new FileStream(filename, FileMode.Open);
            customers = (CustomersDB)serializer.Deserialize(fs);
            fs.Close();
        }

        //MANTENIMIENTO DE PRODUCTOS
        //Ingresar producto:

        public static void addProduct(Product p)
        {
            products.Add(p);
        }

        //Obtener producto(s):

        public static Product getProductById(int id)
        {
            return products.QueryById(id);
        }

        public static List<Product> getAllProducts()
        {
            return products.Values;
        }

        //Modificar producto: Retorna 1 cuando la modificación fue un éxito y 0 cuando falló

        public static int updateProduct(Product p)
        {
            products.Update(p);
            return 1;
        }

        //Eliminar producto: Retorna 1 cuando el borrado fue exitoso, 0 cuando falló

        public static int deleteProduct(int id)
        {
            products.Delete(id);
            return 1;
        }

        //MANTENIMIENTO DE CLIENTES
        //Ingresar nuevo cliente

        public static void addCustomer(Customer c)
        {
            customers.Add(c);
        }

        //Obtener cliente(s)

        public static Customer getCustomerById(int id)
        {
            return customers.QueryById(id);
        }

        public static Customer getCustomerByIdCard(String idCard)
        {
            return null;
        }

        public static List<Customer> getAllCustomers()
        {
            return customers.Values;
        }

        //Modificar cliente

        public static int updateCustomer(Customer c)
        {
            customers.Update(c);
            return 1;
        }

        //Eliminar cliente

        public static int deleteCustomer(String dni)
        {
            customers.Delete(dni);
            return 1;
        }

        //MANTENIMIENTO DE EMPLEADOS
        public static List<Cashier> getAllCashier()
        {
            return cashiers.Values;
        }
        public static List<StoreManager> getAllStoreManager()
        {
            return storeManagers.Values;
        } 

        //MANTENIMIENTO DE CAJEROS
        //Ingresar cajero

        public static void addCashier(Cashier cs)
        {
            cashiers.Add(cs);  
        }

        //Mostrar cajero

        public static Cashier getCashierById(int id)
        {
            /*Cashier c = null;
            for (int i = 0; i < cashierList.Count; i++)
                if (cashierList[i] is Employee)
                {
                    if (((Employee)cashierList[i]).getId() == id)
                    {
                        c = cashierList[i];
                        return c;
                    }
                }

            return c;*/
            return cashiers.getCashierById(id);
        }

        //Modificar cajero

        public static int updateCashier(Cashier cs)
        {
            for (int i = 0; i < cashierList.Count; i++)
                if (cashierList[i].getId() == cs.getId())
                {
                    cashierList[i] = cs;
                    return 1;
                }
            return 0;
        }

        //Eliminar cajero

        public static int deleteCashier(int id)
        {
            cashiers.Delete(id);
            return 1;
        }

        //MANTENIMIENTO DE STORE
        public static void addStore(Store s)
        {
            stores.Add(s);
        }

        //Obtener cliente(s)

        public static Store getStoreById(int id)
        {
            return stores.QueryById(id);
        }

        public static List<Store> getAllStores()
        {
            return stores.Values;
        }

        //Modificar Store

        public static int updateStore(Store c)
        {
            stores.Update(c);
            return 1;
        }

        //Eliminar Store

        public static int deleteStore(int id)
        {
            stores.Delete(id);
            return 1;
        }


        public static void addCashierTerminal(CashierTerminal c) { 
        }

        public static int deleteCashierTerminal(int id) {
            return 1;
        }

        //MANTENIMIENTO DE SALES
        //Ingresar nuevo sale

        public static void addSale(Sale s)
        {
            sales.Add(s);
        }

        //Obtener sale(s)

        public static Sale getSaleById(int id)
        {
            return sales.QueryById(id);
        }


        public static List<Sale> getAllSales()
        {
            return sales.Values;
        }

        //Modificar sale

        public static int updateSale(Sale s)
        {
            sales.Update(s);
            return 1;
        }

        //Eliminar sale

        public static int deleteSale(int id)
        {
            
            return 1;
        }

        //MANTENIMIENTO DE SALES DETAIL

        //Ingresar nuevo sale detail

        public static void addSaleDetail(SalesDetail sd, int saleId)
        {
            saledetails.Add(sd,saleId);  
        }

    }

}
